import os
import re
from concurrent.futures.thread import ThreadPoolExecutor
from string import whitespace

import cv2
import numpy as np

'''
将文件夹中图片拼接为视频
'''

# 完成写入对象的创建，第一个参数是合成之后的视频的名称，第二个参数是可以使用的编码器，第三个参数是帧率即每秒钟展示多少张图片，第四个参数是图片大小信息
def img_to_video(path, save_vedio_path, fps, img_size1, img_size2, img_size3, flag):
    if 1 == flag or 3 == flag or 5 == flag:
        file_path1 = os.path.join(save_vedio_path, os.path.basename(path) + "横屏.mp4")
        if os.path.exists(file_path1):
            os.remove(file_path1)
        # 完成写入对象的创建，第一个参数是合成之后的视频的名称，第二个参数是可以使用的编码器，第三个参数是帧率即每秒钟展示多少张图片，第四个参数是图片大小信息
        videowrite1 = cv2.VideoWriter(file_path1,
                                      cv2.VideoWriter_fourcc(*'mp4v'), fps,
                                      img_size1, True)  # 20是帧数，size是图片尺寸
    if 2 == flag or 3 == flag:
        file_path2 = os.path.join(save_vedio_path, os.path.basename(path) + "竖屏.mp4")
        if os.path.exists(file_path2):
            os.remove(file_path2)
        videowrite2 = cv2.VideoWriter(file_path2,
                                      cv2.VideoWriter_fourcc(*'mp4v'), fps,
                                      img_size2, True)  # 20是帧数，size是图片尺寸
    if 4 == flag or 5 == flag:
        file_path3 = os.path.join(save_vedio_path, os.path.basename(path) + "竖图变横屏.mp4")
        if os.path.exists(file_path3):
            os.remove(file_path3)
        videowrite3 = cv2.VideoWriter(file_path3,
                                      cv2.VideoWriter_fourcc(*'mp4v'), fps,
                                      img_size3, True)  # 20是帧数，size是图片尺寸
    for dirpath, dirnames, filenames in os.walk(path):
        for filename in filenames:
            try:
                if filename.__contains__(".jpg") or filename.__contains__(".png"):
                    inputfilename = os.path.join(dirpath, filename)
                    img = cv2.imread(inputfilename)
                    if img is None:
                        print(filename + " is error!")
                        continue
                    height = len(img)
                    width = len(img[0])
                    if (1 == flag or 3 == flag or 5 == flag) and width > height:
                        img = cv2.resize(img, img_size1, interpolation=cv2.INTER_CUBIC)
                        makeMove(videowrite1, img)
                    if (2 == flag or 3 == flag) and width < height:
                        img = cv2.resize(img, img_size2, interpolation=cv2.INTER_CUBIC)
                        makeMove(videowrite2, img)
                    if (4 == flag or 5 == flag) and width < height:
                        img = cv2.resize(img, img_size2, interpolation=cv2.INTER_CUBIC)
                        final_matrix = np.zeros((img_size3[1], img_size3[0], 3), np.uint8)
                        final_matrix[0:img_size2[1], 0:img_size2[0]] = img
                        final_matrix[0:img_size2[1], img_size2[0]:img_size2[0] * 2] = img
                        final_matrix[0:img_size2[1], img_size2[0] * 2:img_size2[0] * 3] = img
                        makeMove(videowrite3, final_matrix)
            except Exception as f:
                print(f)
                continue
    if 1 == flag or 3 == flag or 5 == flag:
        videowrite1.release()
    if 2 == flag or 3 == flag:
        videowrite2.release()
    if 4 == flag or 5 == flag:
        videowrite3.release()


def makeMove(videoWriter, img):
    height = len(img)
    width = len(img[0])
    # for i in range(1, 5):
    #     height1 = int(height * i * 0.25)
    #     width1 = int(width * i * 0.25)
    #     img1 = cv2.resize(img, (width1, height1), interpolation=cv2.INTER_CUBIC)
    #     final_matrix = np.zeros((height, width, 3), np.uint8)
    #     final_matrix[int((height - height1) / 2):int((height + height1) / 2),
    #     int((width - width1) / 2):int((width + width1) / 2)] = img1
    #     videoWriter.write(final_matrix)
    for i in range(1):
        videoWriter.write(img)


def rename(file_path):
    for dirpath, dirnames, filenames in os.walk(file_path):
        for filename in filenames:
            try:
                inputfilename = dirpath.replace("\\", "/") + '/' + filename
                tables = str.maketrans('', '', "()【】-  */" + r"""!"#$%&'()*+，,-/:;<=>?@[\]^_`{|}~""" + whitespace)
                # 去除中文
                pattern = re.compile(u"[\u4e00-\u9fa5]+")
                filename = re.sub(pattern, "", filename)
                outfilename = dirpath.replace("\\", "/") + '/' + str.strip(filename.translate(tables))
                print('inputfilename:' + inputfilename)
                print('outfilename:' + outfilename)
                if not inputfilename.__eq__(outfilename) and os.path.exists(outfilename):
                     os.remove(outfilename)
                os.rename(inputfilename, outfilename)
            except FileExistsError as f:
                print(f)
                continue


if __name__ == '__main__':
    # path = r'D:\picture\202209'
    path = r'D:\33\22-w'
    save_vedio_path = r'D:\imgtovideo'
    dirflag = 1  # 标记 0遍历path下子文件夹生成子文件夹对应名称视频，1生成path文件夹名视频
    fps = 20  # 帧频（一秒钟多少张图片）
    img_size1 = (3840,2160)  # 横屏分辨率（即图片调整到的分辨率）
    img_size2 = (1200, 1800)  # 竖屏分辨率（即图片调整到的分辨率）
    img_size3 = (3600, 1800)  # 竖屏分辨率（即图片调整到的分辨率）
    flag = 5  # 标记生成视频横屏还是竖屏 1横屏 2竖屏 3（包含1和2） 4竖屏图片横向拼接后生成横屏视频 5（包含1和4）
    if 0 == dirflag:
        dir_names = os.listdir(path)
        print(dir_names)
        with ThreadPoolExecutor(max_workers=5) as f:
            for dirname in dir_names:
                path1 = os.path.join(path, dirname)
                print(path1)
                if os.path.isfile(path1):
                    continue
                rename(path1)
                try:
                    t1 = f.submit(img_to_video, path1, save_vedio_path, fps, img_size1, img_size2, img_size3, flag)
                    # img_to_video(path1, save_vedio_path, fps, img_size1, img_size2, img_size3, flag)
                except Exception as f:
                    print(f)
                    continue
    if 1 == dirflag:
        print(path)
        rename(path)
        try:
            img_to_video(path, save_vedio_path, fps, img_size1, img_size2, img_size3, flag)
        except Exception as f:
            print(f)
